package services

import (
	"database/sql"
	"encoding/json"
	"english_snippet/api/utils"
	"fmt"
	"log"
	"net/http"
)

type Tags struct {
	Data []string `json:"data"`
}

type Snippet struct {
	ID      int    `json:"id"`
	Title   string `json:"title"`
	Content string `json:"content"`
	Tags    Tags   `json:"tags"`
}

func SnippetService(w http.ResponseWriter, r *http.Request) {

	db, err := utils.Link_db()
	if err != nil {
		fmt.Println("Failed to use Link_db")
		http.Error(w, "Database connection error", http.StatusInternalServerError)
		return
	}

	switch r.Method {
	case "GET":

		get_snippet(w, db)

	case "POST":

		create_snippet(w, r, db)

	}

}

func get_snippet(w http.ResponseWriter, db *sql.DB) {
	rows, err := db.Query("SELECT * FROM snippet")
	if err != nil {
		fmt.Println("Failed to use db.Query")
		http.Error(w, "Database query error", http.StatusInternalServerError)
		return
	}

	defer db.Close()

	var snippetData []Snippet

	for rows.Next() {
		var s Snippet
		var tagsJSON string

		err := rows.Scan(&s.ID, &s.Title, &s.Content, &tagsJSON)
		if err != nil {
			fmt.Printf("Error scanning row: %v\n", err)
			continue
		}

		// 解析JSON格式的tags
		if err := json.Unmarshal([]byte(tagsJSON), &s.Tags); err != nil {
			fmt.Printf("Error unmarshaling tags: %v\n", err)
			s.Tags = Tags{Data: []string{}}
		}

		snippetData = append(snippetData, s)
	}

	w.Header().Set("Content-Type", "application/json")

	// 将 snippetData 编码为 JSON 并写入响应
	if err := json.NewEncoder(w).Encode(snippetData); err != nil {
		http.Error(w, "Failed to encode response", http.StatusInternalServerError)
		return
	}
}

func create_snippet(w http.ResponseWriter, r *http.Request, db *sql.DB) {

	var newSnippet Snippet

	err := json.NewDecoder(r.Body).Decode(&newSnippet)
	if err != nil {
		log.Printf("Error decoding request body: %v", err)
		http.Error(w, "Invalid request body", http.StatusBadRequest)
		return
	}

	if newSnippet.Title == "" || newSnippet.Content == "" {
		log.Println("Validation failed: title or content is empty")
		http.Error(w, "Title and content cannot be empty", http.StatusBadRequest)
		return
	}

	// 4. 将 Tags 结构体序列化回 JSON 字符串，以便存入数据库
	tagsJSONBytes, err := json.Marshal(newSnippet.Tags)
	if err != nil {
		log.Printf("Error marshaling tags: %v", err)
		http.Error(w, "Failed to process tags", http.StatusInternalServerError)
		return
	}
	tagsJSONStr := string(tagsJSONBytes)

	query := "INSERT INTO snippet (title, content, tags) VALUES (?, ?, ?)"
	result, err := db.Exec(query, newSnippet.Title, newSnippet.Content, tagsJSONStr)
	if err != nil {
		log.Printf("Failed to insert snippet into database: %v", err)
		http.Error(w, "Failed to create snippet", http.StatusInternalServerError)
		return
	}

	id, err := result.LastInsertId()
	if err != nil {
		log.Printf("Failed to get last insert ID: %v", err)
		http.Error(w, "Failed to retrieve snippet ID", http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")

	w.WriteHeader(http.StatusCreated)

	response := map[string]interface{}{
		"message": "Snippet created successfully",
		"id":      id,
	}

	if err := json.NewEncoder(w).Encode(response); err != nil {
		log.Printf("Failed to encode success response: %v", err)
	}
}
